package com.idol.proxy;

import com.idol.annotation.Autowired;
import com.idol.util.TransactionManager;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author Supreme_Sir
 * @version 1.0
 * @className BeanProxy
 * @description
 * @date 2020/10/14 0:34
 **/
public class BeanProxyFactory {
    @Autowired
    private TransactionManager transactionManager;

    public Object createTransactionProxy(Object bean) {
        Object result = bean;
        if (bean.getClass().getInterfaces().length > 0) {
            result = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {

                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    Object methodResult;
                    try {
                        System.out.println("JDK 动态代理，前置增强");
                        transactionManager.openTransaction();
                        methodResult = method.invoke(bean, args);
                        System.out.println("JDK 动态代理，后置增强");
                        transactionManager.commit();
                    } catch (Exception e) {
                        System.out.println("JDK 动态代理，异常增强");
                        transactionManager.rollback();
                        throw e;
                    }
                    return methodResult;
                }
            });
        } else {
            result = Enhancer.create(bean.getClass(), new MethodInterceptor() {
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    Object methodResult;
                    try {
                        System.out.println("cglib 动态代理，前置增强");
                        transactionManager.openTransaction();
                        methodResult = method.invoke(bean, objects);
                        System.out.println("cglib 动态代理，前置增强");
                        transactionManager.commit();
                    } catch (Exception e) {
                        System.out.println("cglib 动态代理，前置增强");
                        transactionManager.rollback();
                        throw e;
                    }

                    return methodResult;
                }
            });
        }
        return result;
    }
}
